package Master;

import java.util.ArrayList;
import java.util.Collections;

import Master.TaskPlan;

/*
 * For task plans to execute serially
 */
public class PriorityQueue {
	private ArrayList<TaskPlan> taskPlans = null;
	
	public PriorityQueue(ArrayList<TaskPlan> taskPlans){
		this.taskPlans = new ArrayList<TaskPlan>();
		
		//the first taskPlan is always null for index 0
		this.taskPlans.add(null);
		
		if(taskPlans.size() == 1) return;
		
		for(int i = 1; i < taskPlans.size(); i++)
			this.taskPlans.add(taskPlans.get(i));
		buildPriorityQueue();
	}
	
	public void buildPriorityQueue(){
		int i, j, k, n;
		TaskPlan v;
		boolean heap;
		
		if(taskPlans.size() == 1) return;
		n = taskPlans.size() - 1;
		for(i = n/2; i >= 1; i--){
			k = i;
			v = taskPlans.get(k);
			heap = false;
			while(heap == false && 2 * k <= n){
				j = 2 * k;
				if(j < n){
					//if(H[j] < H[j+1]) j++;
					//System.out.println(taskPlans.get(j));
					
					if(taskPlans.get(j).getTimeRequired() > 
							taskPlans.get(j+1).getTimeRequired()) j++;
					/*if(taskPlans.get(j).getPriority() > 
							taskPlans.get(j+1).getPriority()) j++;*/
				}
				
				if(v.getTimeRequired() < taskPlans.get(j).getTimeRequired())
					heap = true;
				/*if(v.getPriority() < taskPlans.get(j).getPriority())
					heap=true;*/
				else{
					//H[k] = H[j];
					taskPlans.set(k, taskPlans.get(j));
					k = j;
				}
			}
			//H[k] = v;
			taskPlans.set(k, v);
		}
		
		sortPriorityQueue();
	}
	
	@SuppressWarnings("unchecked")
	public void sortPriorityQueue(){
		ArrayList<TaskPlan> newTaskPlans = this.taskPlans;
		newTaskPlans.remove(0);
		Collections.sort(newTaskPlans);
		this.taskPlans = new ArrayList<TaskPlan>();
		this.taskPlans.add(null);
		for(int i = 0; i < newTaskPlans.size(); i++)
			this.taskPlans.add(newTaskPlans.get(i));
	}
	
	public TaskPlan deleteATaskPlan(){
		if(taskPlans.size() == 1) return null;
		TaskPlan root = taskPlans.remove(1);
		//H[1] = H[n];
		taskPlans.add(1, taskPlans.get(taskPlans.size() - 1));
		taskPlans.remove(taskPlans.size() - 1);
		if(taskPlans.size() - 1 == 1) return root;
		buildPriorityQueue();		
		return root;
	}
	
	public void insertATaskPlan(TaskPlan taskPlan){
		this.taskPlans.add(taskPlan);
		buildPriorityQueue();
	}

	public ArrayList<TaskPlan> getTaskPlans() {
		return taskPlans;
	}
	
}
